#include "main.h"

using namespace std;

int main(int argc, char * argv[]){
    int j = 0;
    int k = 0,start;
    SYMBOL top;
    if(argc == 1){
        printHelp();
        return 0;
    }
    initTABLE();
    printTABLE();
    push(H);
    push(convert(argv[1][k++]));
    while(!(convert(argv[1][k]) == H && j==2)){
        top = getTop();
        cout<<"Top:\t"<<format(top)<<"\tinput:\t"<<argv[1][k]<<endl;
        printmStack(1, now);
        if(!isGreater(top,convert(argv[1][k]))){
            cout<<"Stop push and process 最左素短语"<<endl;
            start = getHead();

            if(start == -1){
                cout<<"\033[31mError: start can't equal -1\033[0m"<<endl;
                return 1;
            }

            printmStack(start, now);
            cout<<"start:\t"<<start<<"\tvalue:\t"<<format(mStack[start])<<endl;
            // 调用语义处理程序进行加工
            for(start;start<=now;start++){
                pop();
            }
        }else{
            push(convert(argv[1][k]));
            k++;
        }
    }

    return 0;
}

int getHead(){
    int j = now;
    while(j>=0){
        if(isLess(mStack[j],mStack[now])){
            return j;
        }
        j--;
    }
    return -1;
}

void push(SYMBOL x){
    now ++;
    mStack[now] = x;
    cout<<"\033[33mPushing:\t"<<format(x)<<"\033[0m"<<endl;
}

void printmStack(int start, int end){
    int j = 0;
    cout<<"\033[32m";
    for(j = start; j <= end; j++){
        cout<<format(mStack[j]);
    }
    cout<<"\033[0m"<<endl;
}

SYMBOL pop(){
    now--;
    cout<<"\033[34mPoping:\t"<<format(mStack[now+1])<<"\033[0m"<<endl;
    return mStack[now+1];
}

SYMBOL getTop(){
    return mStack[now];
}

bool isLess(SYMBOL x, SYMBOL y){
    if(checkRelation(x,y) == mless)return true;
    return false;
}

bool isGreater(SYMBOL x, SYMBOL y){
    if(checkRelation(x,y) == mgreater)return true;
    return false;
}

Relation checkRelation(SYMBOL x, SYMBOL y){
    int j;
    while(j<count){
        if(table[j].x == x && table[j].y == y){
            if(table[j].relation == mgreater){
                return mgreater;
            }else if(table[j].relation == mless){
                return mless;
            }else if(table[j].relation == mequal){
                return mequal;
            }
        }
        j++;
    }
    // cout<<"\033[31mSome Error happend\033[0m"<<endl;
    return merror;
}

void initTABLE(){
    insertTABLE(p,p,mgreater);
    insertTABLE(M,p,mgreater);
    insertTABLE(U,p,mgreater);
    insertTABLE(i,p,mgreater);
    insertTABLE(L,p,mless);
    insertTABLE(R,p,mgreater);
    insertTABLE(H,p,mless);

    insertTABLE(p,M,mless);
    insertTABLE(M,M,mgreater);
    insertTABLE(U,M,mgreater);
    insertTABLE(i,M,mgreater);
    insertTABLE(L,M,mless);
    insertTABLE(R,M,mgreater);
    insertTABLE(H,M,mless);

    insertTABLE(p,U,mless);
    insertTABLE(M,U,mless);
    insertTABLE(U,U,mless);
    insertTABLE(i,U,mgreater);
    insertTABLE(L,U,mless);
    insertTABLE(R,U,mgreater);
    insertTABLE(H,U,mless);

    insertTABLE(p,i,mless);
    insertTABLE(M,i,mless);
    insertTABLE(U,i,mless);
    insertTABLE(i,i,merror);
    insertTABLE(L,i,mless);
    insertTABLE(R,i,merror);
    insertTABLE(H,i,mless);

    insertTABLE(p,L,mless);
    insertTABLE(M,L,mless);
    insertTABLE(U,L,mless);
    insertTABLE(i,L,merror);
    insertTABLE(L,L,mless);
    insertTABLE(R,L,merror);
    insertTABLE(H,L,mless);

    insertTABLE(p,R,mgreater);
    insertTABLE(M,R,mgreater);
    insertTABLE(U,R,mgreater);
    insertTABLE(i,R,mgreater);
    insertTABLE(L,R,mequal);
    insertTABLE(R,R,mgreater);
    insertTABLE(H,R,merror);

    insertTABLE(p,H,mgreater);
    insertTABLE(M,H,mgreater);
    insertTABLE(U,H,mgreater);
    insertTABLE(i,H,mgreater);
    insertTABLE(L,H,merror);
    insertTABLE(R,H,mgreater);
    insertTABLE(H,H,mequal);
}

void insertTABLE(SYMBOL x, SYMBOL y, Relation relation){
    table[count].x = x;
    table[count].y = y;
    table[count].relation = relation;
    count++;
}

void printTABLE(){
    int j = 0;
    while(j<count){
        cout<<j<<":\tx:\t"<<format(table[j].x)<<"\ty:\t"<<format(table[j].y)<<"\tR:\t"<<fRelation(table[j].relation)<<endl;
        j++;
    }
}

void printHelp(){

}

char format(SYMBOL x){
    switch(x){
        case p:
            return '+';
        case M:
            return '*';
        case U:
            return 94;
        case L:
            return '(';
        case R:
            return ')';
        case H:
            return '#';
        case i:
            return 'i';
        case E:
            return 'E';
        case T:
            return 'T';
        case F:
            return 'F';
        case P:
            return 'P';
    }
}

char fRelation(Relation r){
    switch (r) {
        case mgreater:
            return '>';
        case mless:
            return '<';
        case mequal:
            return '=';
        case merror:
            return '&';
    }
}

SYMBOL convert(char c){
    if(c == '+')return p;
    if(c == '*')return M;
    if(c == 38)return U;
    if(c == '(')return L;
    if(c == ')')return R;
    if(c == '#')return H;
    return i;
}
